#include "CarManager.h"

int CarManager::MAX_SPEED = 180;
int CarManager::MIN_SPEED = 0;

int CarManager::UP= 0;
int CarManager::DOWN= 1;
int CarManager::LEFT= 2;
int CarManager::RIGHT= 3;
int CarManager::STRAIGHT= 4;

CarManager::CarManager(SDL_Surface* screen, Viewport* viewport){
	carRight = GraphDrawer::loadBMP("blueCarRight.bmp");
	carLeft = GraphDrawer::loadBMP("blueCarLeft.bmp");
	carUp = GraphDrawer::loadBMP("blueCarUp.bmp");
	carDown = GraphDrawer::loadBMP("blueCarDown.bmp");
	speedInfraction = GraphDrawer::loadBMP("speedInfraction.bmp");
	speedLim = GraphDrawer::loadBMP("speedLim.bmp");
	wrongDirection = GraphDrawer::loadBMP("wrongDirection.bmp");
	giroIzq = GraphDrawer::loadBMP("giroIzq.bmp");
	giroDer = GraphDrawer::loadBMP("giroDer.bmp");
	mantenerDir = GraphDrawer::loadBMP("mantenerDir.bmp");
	llego = GraphDrawer::loadBMP("llego.bmp");
	vel = GraphDrawer::loadBMP("vel.bmp");
	negro = GraphDrawer::loadBMP("negro.bmp");
	km = GraphDrawer::loadBMP("km.bmp");
	zero = GraphDrawer::loadBMP("zero.bmp");
	one = GraphDrawer::loadBMP("one.bmp");
	two = GraphDrawer::loadBMP("two.bmp");
	three = GraphDrawer::loadBMP("three.bmp");
	four = GraphDrawer::loadBMP("four.bmp");
	five = GraphDrawer::loadBMP("five.bmp");
	six = GraphDrawer::loadBMP("six.bmp");
	seven = GraphDrawer::loadBMP("seven.bmp");
	eigth = GraphDrawer::loadBMP("eigth.bmp");
	nine = GraphDrawer::loadBMP("nine.bmp");

	Color c = c.white;
	Color b = b.black;
	GraphDrawer::makeTransparent(carRight, c);
	GraphDrawer::makeTransparent(carLeft, c);
	GraphDrawer::makeTransparent(carUp, c);
	GraphDrawer::makeTransparent(carDown , c);
	GraphDrawer::makeTransparent(speedInfraction , c);
	GraphDrawer::makeTransparent(speedLim , c);
	GraphDrawer::makeTransparent(wrongDirection , c);
	GraphDrawer::makeTransparent(giroIzq , c);
	GraphDrawer::makeTransparent(giroDer , c);
	GraphDrawer::makeTransparent(mantenerDir , c);
	GraphDrawer::makeTransparent(llego , c);
	GraphDrawer::makeTransparent(vel , c);
	GraphDrawer::makeTransparent(negro , c);
	GraphDrawer::makeTransparent(km , c);
	GraphDrawer::makeTransparent(zero , c);
	GraphDrawer::makeTransparent(one , c);
	GraphDrawer::makeTransparent(two , c);
	GraphDrawer::makeTransparent(three , c);
	GraphDrawer::makeTransparent(four , c);
	GraphDrawer::makeTransparent(five , c);
	GraphDrawer::makeTransparent(six , c);
	GraphDrawer::makeTransparent(seven , c);
	GraphDrawer::makeTransparent(eigth , c);
	GraphDrawer::makeTransparent(nine , c);

	speed = MIN_SPEED;
	car = carRight;

	this->screen = screen;
	this->viewport = viewport;
	int maxDimension = Utils::max(car->w, car->h);
	previous = SDL_CreateRGBSurface(screen->flags, maxDimension, maxDimension, screen->format->BitsPerPixel,
			screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
	panel = SDL_CreateRGBSurface(screen->flags, 150, 110, screen->format->BitsPerPixel,
			screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);
	withNoPanel = SDL_CreateRGBSurface(screen->flags, 150, 110, screen->format->BitsPerPixel,
			screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);

	speedSurface = SDL_CreateRGBSurface(screen->flags, 50, 10, screen->format->BitsPerPixel,
			screen->format->Rmask, screen->format->Gmask, screen->format->Bmask, screen->format->Amask);


	carX = -1;
	carY = -1;
}

CarManager::~CarManager(){
}

int CarManager::getCarX() const {
	return carX;
}

int CarManager::getCarY() const {
	return carY;
}

Vertex* CarManager::getVNext() const {
	return vNext;
}

Edge* CarManager::getActualEdge() const {
	return eActual;
}

void CarManager::calcInitPosition(float& carX, float& carY, Map* map, string idEdgeFrom, int addFrom, string idEdgeTo,GraphDrawer* drawer) {
	Edge *edgefrom = map->getGraph()->getEdge(idEdgeFrom);
	Vertex *origin = map->getGraph()->getVertex(edgefrom->getIdFrom().c_str());
	Vertex *destiny = map->getGraph()->getVertex(edgefrom->getIdTo().c_str());
	float ox=origin->getX();
	float oy=origin->getY();
	float dx=destiny->getX();
	float dy=destiny->getY();
	carX = (( (dx - ox) / ( abs( edgefrom->getLastAddress() - edgefrom->getInitAddress() ) ) ) * (abs (addFrom - edgefrom->getInitAddress())) )+ox;
	carY = (( (dy - oy) / ( abs( edgefrom->getLastAddress() - edgefrom->getInitAddress() ) ) ) * (abs (addFrom - edgefrom->getInitAddress())) )+oy;

	eActual = edgefrom;
	vNext = destiny;
	wrongDir = false;
	
	if (origin->getX() < destiny->getX()) {
		car = carRight;
		currentDirection = RIGHT;
	}
	if (origin->getX() > destiny->getX()) {
		car = carLeft;
		currentDirection = LEFT;
	}
	if (origin->getY() < destiny->getY()) {
		car = carDown;
		currentDirection = DOWN;
	}
	if (origin->getY() > destiny->getY()) {
		car = carUp;
		currentDirection = UP;
	}

	if ((currentDirection == RIGHT) || (currentDirection == LEFT)) {
		carX = drawer->fixXPosition(carX);
		carY = drawer->fixYPosition(carY) - 17;
	}
	else { // ((currentDirection == UP) || (currentDirection == DOWN))
		carX = drawer->fixXPosition(carX) - 17;
		carY = drawer->fixYPosition(carY);
	}
}

bool CarManager::carAtVertex(float vX, float vY){
	
	if (currentDirection == RIGHT) {
		if (((vX - 17) == carX) && (((vY - 20) <= carY) && (carY <= (vY + 20)))) return true;
		return false;
	}
	else if (currentDirection == LEFT) {
		if (((vX - 17) == carX) && (((vY - 20) <= carY) && (carY <= (vY + 20)))) return true;
		return false;
	}
	else if (currentDirection == UP) {
		if ((((vX - 20) <= carX) && (carX <= (vX + 20))) && ((vY - 17) == carY)) return true;
		return false;
	}
	else { //(currentDirection == DOWN)
		if ((((vX - 20) <= carX) && (carX <= (vX + 20))) && ((vY - 17) == carY)) return true;
		return false;
	}
}

void CarManager::drawAll(List* vertexListPath,Vertex* vertex/*, Vertex* additionalVertex*/){
	drawPanel(false, vertexListPath, vertex/*, additionalVertex*/);
	drawCar(carX, carY, false);
}

void CarManager::drawPanel(bool firstTime, List* vertexListPath,Vertex* vertex/*, Vertex* additionalVertex*/) {

	//Vacia el panel
	GraphDrawer::drawIMG(withNoPanel,0,0,panel);

	GraphDrawer::drawIMG(vel,0,0,panel);
	GraphDrawer::drawIMG(km,115,0,panel);
	drawSpeed();
	if(vertexListPath != null) {
		drawNextAction(vertexListPath,vertex/*, additionalVertex*/);
	}
	//last vertex processed, arriving at destiny
	else GraphDrawer::drawIMG(llego,0,20,panel);

	if (checkSpeedLimit())
		GraphDrawer::drawIMG(speedLim,0,50,panel);
	else if (checkSpeedInfraction())
		GraphDrawer::drawIMG(speedInfraction,0,50,panel);

	if (wrongDir) {
		if ((checkSpeedInfraction()) ||(checkSpeedLimit())) GraphDrawer::drawIMG(wrongDirection,0,80,panel);
		else GraphDrawer::drawIMG(wrongDirection,0,50,panel);
	}

	this->viewport->addSurfaceToRenderList(panel, "panel", 0, 0, VIEWPORT_TOP_LEFT);
}

void CarManager::drawCar(int x, int y, bool firstTime){

	viewport->addSurfaceToRenderList(car, "car", x, y, VIEWPORT_ATTACHED);
	carX = x;
	carY = y;
}

void CarManager::drawSpeed() {
	if (speed == 0) {
		GraphDrawer::drawIMG(negro,70,0,panel);
		GraphDrawer::drawIMG(negro,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 10) {
		GraphDrawer::drawIMG(negro,70,0,panel);
		GraphDrawer::drawIMG(one,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 20) {
		GraphDrawer::drawIMG(negro,70,0,panel);
		GraphDrawer::drawIMG(two,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 30) {
		GraphDrawer::drawIMG(negro,70,0,panel);
		GraphDrawer::drawIMG(three,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 40) {
		GraphDrawer::drawIMG(negro,70,0,panel);
		GraphDrawer::drawIMG(four,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 50) {
		GraphDrawer::drawIMG(negro,70,0,panel);
		GraphDrawer::drawIMG(five,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 60) {
		GraphDrawer::drawIMG(negro,70,0,panel);
		GraphDrawer::drawIMG(six,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 70) {
		GraphDrawer::drawIMG(negro,70,0,panel);
		GraphDrawer::drawIMG(seven,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 80) {
		GraphDrawer::drawIMG(negro,70,0,panel);
		GraphDrawer::drawIMG(eigth,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 90) {
		GraphDrawer::drawIMG(negro,70,0,panel);
		GraphDrawer::drawIMG(nine,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 100) {
		GraphDrawer::drawIMG(one,70,0,panel);
		GraphDrawer::drawIMG(zero,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 110) {
		GraphDrawer::drawIMG(one,70,0,panel);
		GraphDrawer::drawIMG(one,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 120) {
		GraphDrawer::drawIMG(one,70,0,panel);
		GraphDrawer::drawIMG(two,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 130) {
		GraphDrawer::drawIMG(one,70,0,panel);
		GraphDrawer::drawIMG(three,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 140) {
		GraphDrawer::drawIMG(one,70,0,panel);
		GraphDrawer::drawIMG(four,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 150) {
		GraphDrawer::drawIMG(one,70,0,panel);
		GraphDrawer::drawIMG(five,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 160) {
		GraphDrawer::drawIMG(one,70,0,panel);
		GraphDrawer::drawIMG(six,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else if (speed == 170) {
		GraphDrawer::drawIMG(one,70,0,panel);
		GraphDrawer::drawIMG(seven,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
	else { // speed == 180
		GraphDrawer::drawIMG(one,70,0,panel);
		GraphDrawer::drawIMG(eigth,85,0,panel);
		GraphDrawer::drawIMG(zero,100,0,panel);
	}
}

void CarManager::drawNextAction(List* vertexListPath,Vertex* vertex/*, Vertex* additionalVertex*/) {
	bool found = false;
	bool useAdditional = false;

/*	if (addition
alVertex != NULL){
		if (vNext->getId() == additionalVertex->getId()){
			//useAdditional = true;
		}
	}*/
	Vertex* v1 = NULL;
	Vertex* v2 = NULL;
	if (!(vertexListPath->empty())) {
		int i = (vertexListPath->getSize() - 1);
		while ((i >= 0) && (!found)) {		
			VertexNode* vertexNode1 = (VertexNode*)vertexListPath->get(i);
			v1 = vertexNode1->getNodeValue();
			if (v1->getId() == vNext->getId()) {			
				if (i > 0) {
					VertexNode* vertexNode2 = (VertexNode*)vertexListPath->get(i-1);
					v2 = vertexNode2->getNodeValue();
				} else { // (i == 0) last vertex
					v2 = vertex;
				}		
				found = true;
			}
			i--;
		}
	}

	/*if (!found){
		if (useAdditional){
			v1 = additionalVertex;
			v2 = vertex;
			found = true;
		}		
	}
*/
	if (found){	
		if (currentDirection == RIGHT) {
			if (v1->getX() < v2->getX()) GraphDrawer::drawIMG(mantenerDir,0,20,panel);
			else if (v1->getY() < v2->getY()) GraphDrawer::drawIMG(giroDer,0,20,panel);
			else if (v1->getY() > v2->getY()) GraphDrawer::drawIMG(giroIzq,0,20,panel);
		}
		else if (currentDirection == LEFT) {
			if (v1->getX() > v2->getX()) GraphDrawer::drawIMG(mantenerDir,0,20,panel);
			else if (v1->getY() < v2->getY()) GraphDrawer::drawIMG(giroIzq,0,20,panel);
			else if (v1->getY() > v2->getY()) GraphDrawer::drawIMG(giroDer,0,20,panel);
		}
		else if (currentDirection == UP) {
			if (v1->getX() < v2->getX()) GraphDrawer::drawIMG(giroDer,0,20,panel);
			else if (v1->getX() > v2->getX()) GraphDrawer::drawIMG(giroIzq,0,20,panel);
			else if (v1->getY() > v2->getY()) GraphDrawer::drawIMG(mantenerDir,0,20,panel);
		}
		else { //if (currentDirection == DOWN)
			if (v1->getX() < v2->getX()) GraphDrawer::drawIMG(giroIzq,0,20,panel);
			else if (v1->getX() > v2->getX()) GraphDrawer::drawIMG(giroDer,0,20,panel);
			else if (v1->getY() < v2->getY()) GraphDrawer::drawIMG(mantenerDir,0,20,panel);
		}
	} else {
		v2 = vertex;
		if (currentDirection == RIGHT) {
			if (vNext->getX() < v2->getX()) GraphDrawer::drawIMG(mantenerDir,0,20,panel);
			else if (vNext->getY() < v2->getY()) GraphDrawer::drawIMG(giroDer,0,20,panel);
			else if (vNext->getY() > v2->getY()) GraphDrawer::drawIMG(giroIzq,0,20,panel);
		}
		else if (currentDirection == LEFT) {
			if (vNext->getX() > v2->getX()) GraphDrawer::drawIMG(mantenerDir,0,20,panel);
			else if (vNext->getY() < v2->getY()) GraphDrawer::drawIMG(giroIzq,0,20,panel);
			else if (vNext->getY() > v2->getY()) GraphDrawer::drawIMG(giroDer,0,20,panel);
		}
		else if (currentDirection == UP) {
			if (vNext->getX() < v2->getX()) GraphDrawer::drawIMG(giroDer,0,20,panel);
			else if (vNext->getX() > v2->getX()) GraphDrawer::drawIMG(giroIzq,0,20,panel);
			else if (vNext->getY() > v2->getY()) GraphDrawer::drawIMG(mantenerDir,0,20,panel);
		}
		else { //if (currentDirection == DOWN)
			if (vNext->getX() < v2->getX()) GraphDrawer::drawIMG(giroIzq,0,20,panel);
			else if (vNext->getX() > v2->getX()) GraphDrawer::drawIMG(giroDer,0,20,panel);
			else if (vNext->getY() < v2->getY()) GraphDrawer::drawIMG(mantenerDir,0,20,panel);
		}
	}
}


void CarManager::turn(int key){
		if (key == SDLK_UP){
			nextDirection = STRAIGHT;
		} else if (key == SDLK_LEFT){
			nextDirection = LEFT;
		} else if (key == SDLK_RIGHT){
			nextDirection = RIGHT;
		}	
}

void CarManager::updateCarPosition(Map* map,GraphManager* graphManager){

	List* edgesList = vNext->getEdgesList();
	List* edgesContList = map->getGraph()->getAllEdgesToVertex(vNext->getId());
	Edge* edgeDer = NULL;
	Edge* edgeIzq = NULL;
	Edge* edgeCont = NULL;
	Edge* edgeDerW = NULL;
	Edge* edgeIzqW = NULL;
	Edge* edgeContW = NULL;

	//recorrido horizontal
	if (currentDirection == RIGHT) {
		
		for (int i = 0; i < edgesList->getSize(); i++) {
			EdgeNode* edgeNode = (EdgeNode*) edgesList->get(i);
			Edge* edge = edgeNode->getNodeValue();
			Vertex* vertexTo = map->getGraph()->getVertex(edge->getIdTo());
			if (vertexTo->getY() > vNext->getY())
				edgeDer = edge;
			else if (vertexTo->getY() < vNext->getY())
				edgeIzq = edge;
			else if (vertexTo->getX() > vNext->getX())
				edgeCont = edge;
		}
		for (int i = 0; i < edgesContList->getSize(); i++) {
			EdgeNode* edgeNode = (EdgeNode*) edgesContList->get(i);
			Edge* edge = edgeNode->getNodeValue();
			Vertex* vertexTo = map->getGraph()->getVertex(edge->getIdFrom());
			if (vertexTo->getY() > vNext->getY())
				edgeDerW = edge;
			else if (vertexTo->getY() < vNext->getY())
				edgeIzqW = edge;
			else if (vertexTo->getX() > vNext->getX())
				edgeContW = edge;
		}

		if (((edgeDer) || (edgeDerW)) && (nextDirection == RIGHT)) {
			currentDirection = DOWN;
			car = carDown;
			if (edgeDer) {
				eActual = edgeDer;
				vNext = map->getGraph()->getVertex(edgeDer->getIdTo());
				wrongDir = false;
			}
			else if (edgeDerW) {
				graphManager->addPhantomEdge(edgeDerW);
				eActual = graphManager->getPhantomEdge();
				
				vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
				wrongDir = true;
			}
		}
		else if (((edgeIzq)  || (edgeIzqW)) && (nextDirection == LEFT)) {
			currentDirection = UP;
			car = carUp;
			if (edgeIzq) {
				eActual = edgeIzq;
				vNext = map->getGraph()->getVertex(edgeIzq->getIdTo());
				wrongDir = false;
			}
			else if (edgeIzqW) {
				graphManager->addPhantomEdge(edgeIzqW);
				eActual = graphManager->getPhantomEdge();
				
				vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
				wrongDir = true;
			}
		}
		else if (edgeCont) {
			eActual = edgeCont;
			vNext = map->getGraph()->getVertex(edgeCont->getIdTo());
			wrongDir = false;
		}
		else if (edgeContW) {
			graphManager->addPhantomEdge(edgeContW);
			
			eActual = graphManager->getPhantomEdge();
			vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
			wrongDir = true;
		}
		else speed = MIN_SPEED;
	}
	else if (currentDirection == LEFT) {
		for (int i = 0; i < edgesList->getSize(); i++) {
			EdgeNode* edgeNode = (EdgeNode*) edgesList->get(i);
			Edge* edge = edgeNode->getNodeValue();
			Vertex* vertexTo = map->getGraph()->getVertex(edge->getIdTo());
			if (vertexTo->getY() < vNext->getY())
				edgeDer = edge;
			else if (vertexTo->getY() > vNext->getY())
				edgeIzq = edge;
			else if (vertexTo->getX() < vNext->getX())
				edgeCont = edge;
		}
		for (int i = 0; i < edgesContList->getSize(); i++) {
			EdgeNode* edgeNode = (EdgeNode*) edgesContList->get(i);
			Edge* edge = edgeNode->getNodeValue();
			Vertex* vertexTo = map->getGraph()->getVertex(edge->getIdFrom());
			if (vertexTo->getY() < vNext->getY())
				edgeDerW = edge;
			else if (vertexTo->getY() > vNext->getY())
				edgeIzqW = edge;
			else if (vertexTo->getX() < vNext->getX())
				edgeContW = edge;
		}

		if (((edgeDer) || (edgeDerW)) && (nextDirection == RIGHT)) {
			currentDirection = UP;
			car = carUp;
			if (edgeDer) {
				eActual = edgeDer;
				vNext = map->getGraph()->getVertex(edgeDer->getIdTo());
				wrongDir = false;
			}
			else if (edgeDerW) {
				graphManager->addPhantomEdge(edgeDerW);
				eActual = graphManager->getPhantomEdge();
				
				vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
				wrongDir = true;
			}
		}
		else if (((edgeIzq)  || (edgeIzqW)) && (nextDirection == LEFT)) {
			currentDirection = DOWN;
			car = carDown;
			if (edgeIzq) {
				eActual = edgeIzq;
				vNext = map->getGraph()->getVertex(edgeIzq->getIdTo());
				wrongDir = false;
			}
			else if (edgeIzqW) {
				graphManager->addPhantomEdge(edgeIzqW);
				eActual = graphManager->getPhantomEdge();
				
				vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
				wrongDir = true;
			}
		}
		else if (edgeCont) {
			eActual = edgeCont;
			vNext = map->getGraph()->getVertex(edgeCont->getIdTo());
			wrongDir = false;
		}
		else if (edgeContW) {
			graphManager->addPhantomEdge(edgeContW);
			eActual = graphManager->getPhantomEdge();
			
			vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
			wrongDir = true;
		}
		else speed = MIN_SPEED;
	}
	//recorrido vertical
	else if (currentDirection == DOWN) {
		for (int i = 0; i < edgesList->getSize(); i++) {
			EdgeNode* edgeNode = (EdgeNode*) edgesList->get(i);
			Edge* edge = edgeNode->getNodeValue();
			Vertex* vertexTo = map->getGraph()->getVertex(edge->getIdTo());
			if (vertexTo->getX() < vNext->getX())
				edgeDer = edge;
			else if (vertexTo->getX() > vNext->getX())
				edgeIzq = edge;
			else if (vertexTo->getY() > vNext->getY())
				edgeCont = edge;
		}
		for (int i = 0; i < edgesContList->getSize(); i++) {
			EdgeNode* edgeNode = (EdgeNode*) edgesContList->get(i);
			Edge* edge = edgeNode->getNodeValue();
			Vertex* vertexTo = map->getGraph()->getVertex(edge->getIdFrom());
			if (vertexTo->getX() < vNext->getX())
				edgeDerW = edge;
			else if (vertexTo->getX() > vNext->getX())
				edgeIzqW = edge;
			else if (vertexTo->getY() > vNext->getY())
				edgeContW = edge;
		}

		if (((edgeDer) || (edgeDerW)) && (nextDirection == RIGHT)) {
			currentDirection = LEFT;
			car = carLeft;
			if (edgeDer) {
				eActual = edgeDer;
				vNext = map->getGraph()->getVertex(edgeDer->getIdTo());
				wrongDir = false;
			}
			else if (edgeDerW) {
				graphManager->addPhantomEdge(edgeDerW);
				eActual = graphManager->getPhantomEdge();
				
				vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
				wrongDir = true;
			}
		}
		else if (((edgeIzq)  || (edgeIzqW)) && (nextDirection == LEFT)) {
			currentDirection = RIGHT;
			car = carRight;
			if (edgeIzq) {
				eActual = edgeIzq;
				vNext = map->getGraph()->getVertex(edgeIzq->getIdTo());
				wrongDir = false;
			}
			else if (edgeIzqW) {
				graphManager->addPhantomEdge(edgeIzqW);
				eActual = graphManager->getPhantomEdge();
				
				vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
				wrongDir = true;
			}
		}
		else if (edgeCont) {
			eActual = edgeCont;
			vNext = map->getGraph()->getVertex(edgeCont->getIdTo());
			wrongDir = false;
		}
		else if (edgeContW) {
			graphManager->addPhantomEdge(edgeContW);
			eActual = graphManager->getPhantomEdge();
			
			vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
			wrongDir = true;
		}
		else speed = MIN_SPEED;
	}
	else {//(currentDirection == UP)
		for (int i = 0; i < edgesList->getSize(); i++) {
			EdgeNode* edgeNode = (EdgeNode*) edgesList->get(i);
			Edge* edge = edgeNode->getNodeValue();
			Vertex* vertexTo = map->getGraph()->getVertex(edge->getIdTo());
			if (vertexTo->getX() > vNext->getX())
				edgeDer = edge;
			else if (vertexTo->getX() < vNext->getX())
				edgeIzq = edge;
			else if (vertexTo->getY() < vNext->getY())
				edgeCont = edge;
		}
		for (int i = 0; i < edgesContList->getSize(); i++) {
			EdgeNode* edgeNode = (EdgeNode*) edgesContList->get(i);
			Edge* edge = edgeNode->getNodeValue();
			Vertex* vertexTo = map->getGraph()->getVertex(edge->getIdFrom());
			if (vertexTo->getX() > vNext->getX())
				edgeDerW = edge;
			else if (vertexTo->getX() < vNext->getX())
				edgeIzqW = edge;
			else if (vertexTo->getY() < vNext->getY())
				edgeContW = edge;
		}

		if (((edgeDer) || (edgeDerW)) && (nextDirection == RIGHT)) {
			currentDirection = RIGHT;
			car = carRight;
			if (edgeDer) {
				eActual = edgeDer;
				vNext = map->getGraph()->getVertex(edgeDer->getIdTo());
				wrongDir = false;
			}
			else if (edgeDerW) {
				graphManager->addPhantomEdge(edgeDerW);
				eActual = graphManager->getPhantomEdge();
				
				vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
				wrongDir = true;
			}
		}
		else if (((edgeIzq)  || (edgeIzqW)) && (nextDirection == LEFT)) {
			currentDirection = LEFT;
			car = carLeft;
			if (edgeIzq) {
				eActual = edgeIzq;
				vNext = map->getGraph()->getVertex(edgeIzq->getIdTo());
				wrongDir = false;
			}
			else if (edgeIzqW) {
				graphManager->addPhantomEdge(edgeIzqW);
				eActual = graphManager->getPhantomEdge();
				
				vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
				wrongDir = true;
			}
		}
		else if (edgeCont) {
			eActual = edgeCont;
			vNext = map->getGraph()->getVertex(edgeCont->getIdTo());
			wrongDir = false;
		}
		else if (edgeContW) {
			graphManager->addPhantomEdge(edgeContW);
			eActual = graphManager->getPhantomEdge();
			
			vNext = map->getGraph()->getVertex(graphManager->getPhantomEdge()->getIdTo());
			wrongDir = true;
		}
		else speed = MIN_SPEED;
	}
	nextDirection = STRAIGHT;
}

void CarManager::speedUp() {
	speed = speed + 10;
	if (speed > MAX_SPEED){
		speed = MAX_SPEED;
	}
}

void CarManager::speedDown() {
	speed = speed - 10;
	if (speed < MIN_SPEED){
		speed = MIN_SPEED;
	}
}

bool CarManager::checkSpeedLimit() {
	if (speed == eActual->getMaxVelocity()) {
		return true;
	}
	return false;
}

bool CarManager::checkSpeedInfraction() {
	if (speed > eActual->getMaxVelocity()) {
		return true;
	}
	return false;
}

void CarManager::timePasses() {
	if (speed > 0){
		int offset = 1;
		if (currentDirection == UP){
			carY = carY - offset;
		} else if (currentDirection == DOWN){
			carY = carY + offset;
		} else if (currentDirection == LEFT){
			carX = carX - offset;
		} else if (currentDirection == RIGHT){
			carX = carX + offset;
		}
	}
}

int CarManager::getSleep(){
	if (speed == 0){
		return 0;
	}
	double coef = eActual->getLength() / 100;
	double r = speed / 60.0;
	double delay = 60.0 / r;
	delay = delay * coef;
	return delay;
}

/*
void CarManager::drawSurfaceAt(SDL_Surface* from, int x, int y, SDL_Surface* to){
	GraphDrawer::drawIMG(from,x,y,screen);
	//SDL_Flip(screen);
	//viewport->drawSurfaceAt(from, x, y);
}
*/
